package com.ruoyi.server.server;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.server.encode.ReceiveSendEncode;
import com.ruoyi.server.encode.SendReceiveDecode;
import com.ruoyi.server.enums.AddConstants5;
import com.ruoyi.server.enums.CmdConstants;
import com.ruoyi.server.enums.DeleteConstants6;
import com.ruoyi.server.login.LoginReader;
import com.ruoyi.server.login.LoginWriter;
import com.ruoyi.server.read.BaseCenterReader;
import com.ruoyi.server.login.FocusWriterReader;
import com.ruoyi.server.read.GroupReader;
import com.ruoyi.server.read.PrivateReader;
import com.ruoyi.server.thread.PullReceiptReader;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;


/**
 *  控制中心
 *
 * @author OpenACloud
 * @date 2024-06-05
 */
@Component
public class ChatServer {

    @Resource
    private LoginReader authLoginReader;
    @Resource
    private PrivateReader privateReader;
    @Resource
    private GroupReader groupReader;
    @Resource
    private RedisCache redisCache;

    @PostConstruct
    public void start()  {

        HashMap<Byte, BaseCenterReader> baseReaderMaps = new HashMap<>();
        baseReaderMaps.put(CmdConstants.PRIVATE_CMD, privateReader);
        baseReaderMaps.put(CmdConstants.GROUP_CMD, groupReader);
        baseReaderMaps.put(AddConstants5.ADD_FRIEND, privateReader);
        baseReaderMaps.put(AddConstants5.AP_ADD_FRIEND, privateReader);
        baseReaderMaps.put(DeleteConstants6.DELETE_FRIEND, privateReader);

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel ch) {
                        ChannelPipeline pipeline = ch.pipeline();
                        //pipeline.addLast(new IdleStateHandler(120, 0, 0, TimeUnit.SECONDS));
                        pipeline.addLast(new HttpServerCodec());
                        pipeline.addLast(new HttpObjectAggregator(65535));
                        pipeline.addLast(new ChunkedWriteHandler());
                        pipeline.addLast(authLoginReader);      //HTTP 认证handler了, 通过请求头Auth进行认证, 如果认证失败直接返回
                        pipeline.addLast(new WebSocketServerProtocolHandler("/open"));
                        //pipeline.addLast(new LoginWriter());    //认证成功后, 返回Rsp信息, 在Rep中添加请求头AuthCode, 添加动态码与通道绑定, 保证消息的正确型
                        pipeline.addLast(new FocusWriterReader(privateReader, redisCache));
                        pipeline.addLast(new SendReceiveDecode(baseReaderMaps));        //解码器, 处理TextWebSocketFrame请求，转换成SendMsg
                        pipeline.addLast(privateReader);                                // 处理消息
                        pipeline.addLast(new ReceiveSendEncode());                      //编码器, 对SendMsg消息转换成String类型进行返回

                    }
                })
                .option(ChannelOption.SO_BACKLOG, 5)
                .childOption(ChannelOption.SO_KEEPALIVE, true);
        try {
            bootstrap.bind(7777).sync().channel();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("-----------------------------------------> Server StartUp!!!!");
    }


}
